#include "TLC5940.h"

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
cTLC5940::cTLC5940( )
{
	at_Sin = 11;
	at_Sclk = 13;
	at_Xlat = 3;
	at_Gsclk = 3; // PWM
	at_Blank = 2; // Global ON/OFF
	
	pinMode(at_Sin, OUTPUT); 
	pinMode(at_Sclk, OUTPUT); 
	pinMode(A3, OUTPUT);
	pinMode(at_Gsclk, OUTPUT);
	pinMode(at_Blank, OUTPUT);
	
	at_PwmCounter = 0; 
	at_Pwm = 50; // 50% Initial PWM
	
	me_Init();
}
// ---------------------------------------------------------------------------
// Desctructor
// ---------------------------------------------------------------------------
cTLC5940::~cTLC5940()
{
	me_Init( );
}
// ---------------------------------------------------------------------------		
// Initialise		
// ---------------------------------------------------------------------------
void cTLC5940::me_Init()
{
	uint8_t i;
	
	digitalWrite(at_Blank, HIGH); 
	
	digitalWrite(A3, LOW);
	digitalWrite(at_Sclk, LOW);
	
	digitalWrite(at_Sin, LOW);
	for (i = 0; i < 16; i++)
	{
		at_Pins[i] = LOW;
		me_ClockData( );	
	} // for i
	me_LatchData( );
	
	digitalWrite(at_Blank, LOW);
}
// ---------------------------------------------------------------------------		
void cTLC5940::me_ClockData( )
{
	digitalWrite(at_Sclk, HIGH);
	delayMicroseconds(1); // us
	digitalWrite(at_Sclk, LOW);
	delayMicroseconds(1); // us
}
// ---------------------------------------------------------------------------		
void cTLC5940::me_LatchData( )
{
	digitalWrite(A3, HIGH);
	delayMicroseconds(1); // us
	digitalWrite(A3, LOW);
	delayMicroseconds(1); // us
}
// ---------------------------------------------------------------------------		
void cTLC5940::me_UpdateOutput( )
{
	uint8_t i;	
	
	for (i = 0; i < 16; i++)
	{
		digitalWrite(at_Sin, at_Pins[i]); // LOW
		me_ClockData( );
	} // for i
	me_LatchData( );	
}
// ---------------------------------------------------------------------------
void cTLC5940::me_SetPin(uint8_t pin, boolean state)
{
	if (pin < NUMBER_OF_PINS)
	{
		at_Pins[pin] = state;	
	} // else invalid
}
// ---------------------------------------------------------------------------
void cTLC5940::me_SetPins(uint16_t pins)
{
	uint16_t i, p;
	
	p = 0x8000;
	for (i = 0; i < 16; i++)
	{
		at_Pins[i] = (pins & p) ? true : false;
		p >>= 1;
	} // for i
	
	at_Pwm = 50;
}
// ---------------------------------------------------------------------------
void cTLC5940::me_SetPwm(uint16_t pwm)
{
	if (pwm <= MAX_PWM)
	{
		at_Pwm = pwm;
	} // else invalid
}
// ---------------------------------------------------------------------------
void cTLC5940::me_PwmTick( )
{
	at_PwmCounter++;
	if (at_PwmCounter >= MAX_PWM)
	{
		at_PwmCounter = 0;
	}
	
	if (at_Pwm > at_PwmCounter)
	{
		digitalWrite(at_Gsclk, HIGH);
	}
	else
	{
		digitalWrite(at_Gsclk, LOW);
	}
}
// ---------------------------------------------------------------------------
